#include "UdpServer.hpp"
#include <pthread.h>

void Usage(string s)
{
    s += " ip port";
    cout << s << endl;
}

struct SockInfo
{
    int _sockfd;
    sockaddr_in _sockin;
};

void *SendFun(void *args)
{
    SockInfo *sockinfo = static_cast<SockInfo *>(args);
    socklen_t len = sizeof(sockinfo->_sockin);
    string s;
    while (true)
    {
        cout << "Enter message @ ";
        getline(cin, s);

        int res = sendto(sockinfo->_sockfd, s.c_str(), s.size(), 0, (sockaddr *)(&(sockinfo->_sockin)), len);
        if (res == -1)
        {
            lg(Error, "client send to server fail,errno:%d,message:%s", errno, strerror(errno));
            continue;
        }
    }

    return nullptr;
}

void *RcvFun(void *args)
{
    SockInfo *sockinfo = static_cast<SockInfo *>(args);

    while (true)
    {
        char buffer[1024];
        sockaddr_in temp;
        socklen_t tempLen = sizeof(temp);
        int num = recvfrom(sockinfo->_sockfd, buffer, sizeof(buffer), 0, (sockaddr *)&temp, &tempLen);
        if (num == -1)
        {
            lg(Error, "client receive from server fail,errno:%d,message:%s", errno, strerror(errno));
            continue;
        }
        buffer[num] = '\0';
        cout << buffer << endl;
    }

    return nullptr;
}

// .udpclient ip port
int main(int argc, char *argv[])
{
    // if (argc != 3)
    // {
    //     Usage(argv[0]);
    //     return 0;
    // }

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        lg(Fatal, "create socket fail,errno:%d,message:%s", errno, strerror(errno));
        exit(SOCKET_CREATE);
    }
    lg(Info, "create socket success,sokcet:%d", sockfd);

    // 客户端会在发送第一条消息的时候自动绑定socket
    // 意思就是客户端也需要绑定就是是自动绑定，不是主动绑定

    sockaddr_in sockin;
    bzero(&sockin, sizeof(sockin));
    uint16_t serverPort = stoi(argv[2]);

    sockin.sin_family = AF_INET;
    sockin.sin_addr.s_addr = inet_addr(argv[1]);
    sockin.sin_port = htons(serverPort);

    socklen_t len = sizeof(sockin);

    SockInfo sockinfo = {sockfd, sockin};

    // 引入多线程使得客户端的发送和接收分离
    pthread_t sendClient, rcvClient;
    pthread_create(&sendClient, nullptr, SendFun, &sockinfo);
    pthread_create(&rcvClient, nullptr, RcvFun, &sockinfo);

    pthread_join(sendClient,nullptr);
    pthread_join(rcvClient,nullptr);

    // string s;
    // while (true)
    // {
    //     cout << "Enter message @ ";
    //     getline(cin, s);

    //     int res = sendto(sockfd, s.c_str(), s.size(), 0, (sockaddr *)&sockin, len);
    //     if (res == -1)
    //     {
    //         lg(Error, "client send to server fail,errno:%d,message:%s", errno, strerror(errno));
    //         continue;
    //     }

    //     char buffer[1024];
    //     sockaddr_in temp;
    //     socklen_t tempLen = sizeof(temp);
    //     int num = recvfrom(sockfd, buffer, sizeof(buffer), 0, (sockaddr *)&temp, &tempLen);
    //     if (num == -1)
    //     {
    //         lg(Error, "client receive from server fail,errno:%d,message:%s", errno, strerror(errno));
    //         continue;
    //     }
    //     buffer[num] = '\0';
    //     cout << buffer << endl;
    // }
}